import Singleton from "../design-pattern/Singleton";

const { ccclass, property } = cc._decorator;

@ccclass
export default class AssetMgr extends Singleton {
    /**加载成功的bundle */
    private _bundleMap: Map<string, cc.AssetManager.Bundle> = new Map<string, cc.AssetManager.Bundle>();
    public get bundleMap() { return this._bundleMap }
    /**
     * 加载bundle(一个或多个)
     * @param bundleUrls bundle 路径
     * @param cbFinish 加载完成后的回调
     * @param isLoadByOne 可选参数，是否一个一个下载，默认同时下载
     */
    public loadBundle(
        bundleUrls: string | string[],
        cbFinish: (err: Error, bundleLoadList: cc.AssetManager.Bundle[]) => void,
        isLoadByOne: boolean = false,
    ) {
        if (typeof bundleUrls === `string`)
            bundleUrls = [bundleUrls];
        const len = bundleUrls.length;
        const faillList: string[] = [];
        const bundleList: cc.AssetManager.Bundle[] = [];
        const loadOne = (url: string, onFinish?: (isFinish: boolean) => void): void => {
            cc.assetManager.loadBundle(url, (err: Error, bundle: cc.AssetManager.Bundle) => {
                if (err) {
                    console.error('加载bundle错误:', url, err.message || err);
                    faillList.push(url);
                } else {
                    console.log('加载bundle成功', url, bundle);
                    bundleList.push(bundle);
                    this._bundleMap.set(this.getBundleNameFromPath(url),bundle)
                }
                const isFinish = faillList.length + bundleList.length === len;
                if (isFinish) {
                    //全部都加载了
                    //1.如果有失败的
                    if (faillList.length > 0) {
                        cbFinish(
                            new Error(`loadBundle未全部下载成功，失败列表:${faillList.toString()}`),
                            bundleList
                        );
                    }
                    //2.全部都加载成功
                    else {
                        cbFinish(null, bundleList);
                    }
                }
                onFinish && onFinish(isFinish);
            });
        };
        //如果需要一个个下载
        if (isLoadByOne) {
            let i = 0;
            const loadByOne = (): void => {
                loadOne(bundleUrls[i], (isFinish: boolean) => {
                    if (!isFinish) {
                        i++;
                        loadByOne();
                    };
                });
            };
        }
        //如果一起下载
        else {
            for (let i = 0; i < len; i++) {
                const url = bundleUrls[i];
                loadOne(url);
            }
        }
    }
    /**
     * 路径解析，分离出bundle名
     * */
    private getBundleNameFromPath(url: string) {
        const arr = url.split('/');
        let bundleName = '';
        if (arr.length > 1) {
            bundleName = arr[arr.length - 1];
        }
        return bundleName;
    }
 
    public load<T extends typeof cc.Asset>(
        url: string,
        type: T,
        cb: (err: Error, res: InstanceType<T>) => void,
    ) {
         //判断是否是远程资源
         if (url.startsWith('http')) {
         }
         else{
             
         }
    }


    /**
     * 分帧加载
     * @param com 加载的脚本this
     * @param cbLoad 加载函数   
     * @param number 一帧加载个数
     * @param totalNum 需要加载的总数
     */
    public loadByFrame(com: cc.Component, cbLoad: Function, number: number, totalNum: number) {
        let index = 0;
        const load = () => {
            for (let i = 0; i < number; i++) {
                cbLoad && cbLoad(index++)
            }
            if (index < totalNum) {
                com.scheduleOnce(() => load());
            }
        }
        load()
    }
}
